;;; -*- Mode: LISP; Syntax: ANSI-COMMON-LISP -*-

(setf *lalr-debug* t)

(defparameter grammar '((input --> identifier equals expression         #'(lambda (identifier equals expression)
									    (declare (ignore equals))
									    `(equals ',identifier ',expression)))
			(input --> expression                           #'(lambda (expression)
									    expression))
			(expression --> number plus number              #'(lambda (exp1 plus exp2)
									    (print "here!")
									    `(op ',exp1 ',exp2)))
			(expression --> num-or-ident                    #'(lambda (num-or-ident)
									    num-or-ident))
			(num-or-ident --> number                        #'(lambda (number)
									    number))
			(num-or-ident --> identifier                    #'(lambda (identifier)
									    `(lookup ',identifier)))))

(defun parse-line (words)
  (labels ((lookup (word)
                   (cond ((numberp word) 'number)
			 ((eq word '=) 'equals)
			 ((eq word 'plus) 'plus)
	;		 ((member word '(* / + -)) 'op)
			 ((eq word '$) '$)
			 ((symbolp word) 'identifier)))
           (next-input ()
                       (let* ((word (pop words))
                              (cat (lookup word)))
			 (cons cat                  ; category
                               (list cat word))))   ; value
           (parse-error ()
                        (format nil "Error before ~a" words)))
    (lalr-parser #'next-input #'parse-error)))

(make-parser grammar lexforms '$)


(parse-line '(18 $))
(parse-line '(foo $))
(parse-line '(foo = 18 $))
(parse-line '(12 plus 2 $))
(parse-line '(x = 5 + 7 * 3 $))
